using JGSY.CMS.LowCode.Platform.Domain.Entities;
using JGSY.CMS.LowCode.Platform.Domain.Enums;
using JGSY.CMS.LowCode.Platform.Domain.Interfaces;
using JGSY.CMS.LowCode.Platform.Infrastructure.CmsDbContext;
using Microsoft.EntityFrameworkCore;
using System.Linq.Expressions;

namespace JGSY.CMS.LowCode.Platform.Infrastructure.Repositories
{
    /// <summary>
    /// 工作流实例仓储实现
    /// </summary>
    public class WorkflowInstanceRepository : Repository<WorkflowInstance>, IWorkflowInstanceRepository
    {
        public WorkflowInstanceRepository(LowCodeDbContext context) : base(context)
        {
        }

        /// <summary>
        /// 根据工作流ID获取实例列表
        /// </summary>
        public async Task<List<WorkflowInstance>> GetByWorkflowIdAsync(long workflowId)
        {
            return await _context.WorkflowInstances
                .Where(x => x.WorkflowId == workflowId)
                .OrderByDescending(x => x.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 根据发起人获取实例列表
        /// </summary>
        public async Task<List<WorkflowInstance>> GetByInitiatorAsync(long initiatorId)
        {
            return await _context.WorkflowInstances
                .Where(x => x.InitiatorId == initiatorId)
                .OrderByDescending(x => x.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 获取运行中的实例列表
        /// </summary>
        public async Task<List<WorkflowInstance>> GetRunningInstancesAsync()
        {
            return await _context.WorkflowInstances
                .Where(x => x.Status == WorkflowInstanceStatus.Pending || 
                           x.Status == WorkflowInstanceStatus.Running)
                .OrderBy(x => x.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 获取超时的实例列表（WorkflowInstance 实体没有 TimeoutAt 属性，返回空列表）
        /// </summary>
        public async Task<List<WorkflowInstance>> GetTimeoutInstancesAsync()
        {
            await Task.CompletedTask;
            return new List<WorkflowInstance>();
        }

        /// <summary>
        /// 获取执行统计（简化实现）
        /// </summary>
        public async Task<Dictionary<string, int>> GetExecutionStatisticsAsync(long workflowId)
        {
            var instances = await _context.WorkflowInstances
                .Where(x => x.WorkflowId == workflowId)
                .ToListAsync();

            return new Dictionary<string, int>
            {
                ["Total"] = instances.Count,
                ["Pending"] = instances.Count(x => x.Status == WorkflowInstanceStatus.Pending),
                ["Running"] = instances.Count(x => x.Status == WorkflowInstanceStatus.Running),
                ["Completed"] = instances.Count(x => x.Status == WorkflowInstanceStatus.Completed),
                ["Failed"] = instances.Count(x => x.Status == WorkflowInstanceStatus.Failed)
            };
        }

        /// <summary>
        /// 批量更新实例状态
        /// </summary>
        public async Task<int> BatchUpdateStatusAsync(List<long> instanceIds, WorkflowInstanceStatus status)
        {
            var instances = await _context.WorkflowInstances
                .Where(x => instanceIds.Contains(x.Id))
                .ToListAsync();

            foreach (var instance in instances)
            {
                instance.Status = status;
                instance.UpdatedAt = DateTime.UtcNow;
                
                if (status == WorkflowInstanceStatus.Completed ||
                    status == WorkflowInstanceStatus.Failed)
                {
                    instance.CompletedAt = DateTime.UtcNow;
                }
            }

            return await _context.SaveChangesAsync();
        }

        /// <summary>
        /// 清理已完成的实例
        /// </summary>
        public async Task<int> CleanupCompletedInstancesAsync(int daysOld = 30)
        {
            var cutoffDate = DateTime.UtcNow.AddDays(-daysOld);
            
            var instancesToDelete = await _context.WorkflowInstances
                .Where(x => (x.Status == WorkflowInstanceStatus.Completed || 
                            x.Status == WorkflowInstanceStatus.Failed) &&
                           x.CompletedAt.HasValue && 
                           x.CompletedAt < cutoffDate)
                .ToListAsync();

            if (instancesToDelete.Any())
            {
                _context.WorkflowInstances.RemoveRange(instancesToDelete);
                return await _context.SaveChangesAsync();
            }

            return 0;
        }

        /// <summary>
        /// 根据状态获取实例列表
        /// </summary>
        public async Task<IEnumerable<WorkflowInstance>> GetByStatusAsync(WorkflowInstanceStatus status, int pageIndex = 1, int pageSize = 20)
        {
            return await _context.WorkflowInstances
                .Where(x => x.Status == status)
                .Skip((pageIndex - 1) * pageSize)
                .Take(pageSize)
                .OrderByDescending(x => x.CreatedAt)
                .ToListAsync();
        }

        /// <summary>
        /// 批量更新实例状态（接受 string 类型状态）
        /// </summary>
        public async Task<bool> BatchUpdateStatusAsync(List<long> ids, string status)
        {
            // 尝试解析字符串状态为枚举
            if (Enum.TryParse<WorkflowInstanceStatus>(status, out var enumStatus))
            {
                var count = await BatchUpdateStatusAsync(ids, enumStatus);
                return count > 0;
            }
            return false;
        }

        /// <summary>
        /// 清理已完成的实例（接受 DateTime 类型）
        /// </summary>
        public async Task<int> CleanupCompletedInstancesAsync(DateTime beforeDate)
        {
            var instancesToDelete = await _context.WorkflowInstances
                .Where(x => (x.Status == WorkflowInstanceStatus.Completed || 
                            x.Status == WorkflowInstanceStatus.Failed) &&
                           x.CompletedAt.HasValue && 
                           x.CompletedAt < beforeDate)
                .ToListAsync();

            if (instancesToDelete.Any())
            {
                _context.WorkflowInstances.RemoveRange(instancesToDelete);
                return await _context.SaveChangesAsync();
            }

            return 0;
        }
    }
}
